import { useEffect, useState, useRef } from "react";
import "./styles.css";
import { playerImg, enemyImage, boomImg } from "./images";
import { forEach } from "lodash";
import usePlayer from "./usePlayer";
import useBullet from "./useBullet";
import useEnemy from "./useEnemy";
const canvasWidth = 500;
const canvasHeight = 500;
let startTimer = null;
const FPS = 31;
export default function App() {
const [score, setScore] = useState(0);
const [playerBullets, setPlayerBullets] = useState([]);
const [playerEnemys, setPlayerEnemys] = useState([]);
const playerImgRef = useRef(null);
const enemyImgRef = useRef(null);
const enemyBoomImgRef = useRef(null);
const canvasRef = useRef(null);
const [ctx, setCtx] = useState(null);
useEffect(() => {
console.log("playerEnemys", playerEnemys);
}, [playerEnemys]);
const endGame = () => {
clearInterval(startTimer);
setScore(0);
setPlayerBullets([]);
setPlayerEnemys([]);
playerImgRef.current.img = playerImg;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
};
useEffect(() => {
if (canvasRef.current) setCtx(canvasRef.current.getContext("2d"));
}, [canvasRef]);
const { bullet, drawBullet, explodeBullet, setBullet } = useBullet({ ctx });
const { player, drawPlayer, updatePlayer, explodPlayer } = usePlayer({
endGame,
ctx,
setPlayerBullets,
setBullet,
bullet,
playerImgRef
});
const { E, setE, explodeE, drawE, enemyImg, active } = useEnemy({
ctx,
enemyImgRef
});
const startGame = () => {
update();
// draw();
// if (ctx) {
// startTimer = setInterval(function () {
// update();
// draw();
// }, 1000 / FPS);
// }
};
const draw = () => {
if (ctx) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
drawPlayer();
forEach(playerBullets, (bullet) => {
drawBullet();
});
forEach(playerEnemys, (enemy) => {
drawE();
});
}
};
const update = () => {
forEach(playerBullets, (bullet, index, object) => {
setBullet((prev) => {
return { ...prev, y: prev.y - prev.speed };
});
if (bullet?.y < 0 || bullet?.active) {
object.splice(index, 1);
}
});
forEach(playerEnemys, (enemy, index, object) => {
setE((prev) => ({ ...prev, y: prev.y + enemy.speed }));
if (enemy.y > canvasHeight || enemy.active) {
setScore((prev) => prev + 1);
object.splice(index, 1);
}
});
console.log(Math.random(), Math.random() < 0.02);
if (Math.random() < 0.5) {
console.log("add");
setPlayerEnemys((prev) => [...prev, { ...E }]);
}
handleCollisions();
};
const handleCollisions = () => {
forEach(playerBullets, (bullet) => {
forEach(playerEnemys, (enemy) => {
if (collides(bullet, enemy)) {
explodeBullet();
explodeE();
}
});
});
forEach(playerEnemys, (enemy) => {
if (collides(enemy, player)) {
explodeE();
explodPlayer();
}
});
};
const collides = (a, b) => {
return (
a.x < b.x + b.width &&
a.x + a.width > b.x &&
a.y < b.y + b.height &&
a.y + a.height > b.y
);
};
return (
<div className="App">
<button className="startBtn" onClick={startGame}>
Start
</button>
<div> Score:{score}</div>
<br />
<canvas
ref={canvasRef}
width={canvasWidth}
height={canvasHeight}
></canvas>
<img alt="" className="playerImg" ref={playerImgRef} src={playerImg} />
<img alt="" className="enemyImg" ref={enemyImgRef} src={enemyImage} />
<img
alt=""
className="enemyBoomImg"
ref={enemyBoomImgRef}
src={boomImg}
/>
</div>
);
}
待完成
https://codesandbox.io/s/tie-ren-sai-she-ji-you-xi-g0kob?file=/src/App.js:0-3833